package com.mcppro.aidatabase.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mcppro.aidatabase.dto.IntentDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

/**
 * AI意图解析服务
 * 
 * @author MCP Pro
 */
@Service
@Slf4j
public class IntentAnalysisService {

    private final SiliconFlowService siliconFlowService;
    private final ObjectMapper objectMapper;

    @Autowired
    public IntentAnalysisService(SiliconFlowService siliconFlowService, ObjectMapper objectMapper) {
        this.siliconFlowService = siliconFlowService;
        this.objectMapper = objectMapper;
    }

    /**
     * 解析用户意图
     * 
     * @param userQuestion 用户问题
     * @return 意图解析结果
     */
    public Mono<IntentDto.IntentResult> analyzeIntent(String userQuestion) {
        log.debug("开始解析用户意图: {}", userQuestion);

        String systemPrompt = buildSystemPrompt();
        String userPrompt = buildUserPrompt(userQuestion);

        return siliconFlowService.chat(userPrompt, systemPrompt)
                .map(this::parseIntentFromResponse)
                .doOnSuccess(intent -> log.debug("意图解析成功: {}", intent))
                .doOnError(error -> log.error("意图解析失败", error));
    }

    /**
     * 构建系统提示词
     */
    private String buildSystemPrompt() {
        return """
                你是一个专业的数据库查询意图解析助手。你的任务是将用户的自然语言问题转换为结构化的数据库操作意图。
                
                数据库包含以下表结构：
                
                1. users表 (用户表):
                   - id: 主键 (BIGINT) - 自动生成，不需提供
                   - username: 用户名 (VARCHAR) - 必填
                   - email: 邮箱 (VARCHAR) - 必填
                   - full_name: 全名 (VARCHAR) - 可选
                   - age: 年龄 (INT) - 可选
                   - status: 状态 (ENUM: ACTIVE, INACTIVE, SUSPENDED) - 默认ACTIVE
                   - created_at: 创建时间 (TIMESTAMP) - 自动生成，不需提供
                   - updated_at: 更新时间 (TIMESTAMP) - 自动生成，不需提供
                
                请严格按照以下JSON格式返回解析结果，不要添加任何其他文字：
                
                {
                  "operation": "SELECT|INSERT|UPDATE|DELETE|COUNT",
                  "table_name": "表名",
                  "fields": ["要查询的字段列表"],
                  "conditions": [
                    {
                      "field": "字段名",
                      "operator": "EQUALS|NOT_EQUALS|GREATER_THAN|LESS_THAN|GREATER_EQUAL|LESS_EQUAL|LIKE|NOT_LIKE|IN|NOT_IN|IS_NULL|IS_NOT_NULL|BETWEEN",
                      "value": "值",
                      "logical": "AND|OR"
                    }
                  ],
                  "update_data": {"字段": "新值"},
                  "insert_data": {"字段": "值"},
                  "order_by": [{"field": "字段名", "direction": "ASC|DESC"}],
                  "limit": 限制数量,
                  "offset": 偏移量,
                  "group_by": ["分组字段"],
                  "aggregations": [{"type": "COUNT|SUM|AVG|MAX|MIN", "field": "字段名", "alias": "别名"}],
                  "original_question": "原始问题",
                  "confidence": 置信度(0.0-1.0)
                }
                
                特别注意事SELECT操作：
                1. 对于查询操作，应优先指定具体字段名，而不是使用"*"
                2. 如果用户没有指定字段，可以留空fields数组或使用常用字段
                3. 常用字段包括：id, username, email, full_name, age, status
                
                特别注意事INSERT操作：
                1. 如果用户没有提供具体数据，请生成合理的示例数据
                2. username必须提供，如果未提供可使用"user_" + 随机数字
                3. email必须提供，如果未提供可使用username + "@example.com"
                4. full_name可以为空，但如果提供可使用用户名
                5. age可以为空，如果提供可设置为25-35之间的值
                6. status默认为ACTIVE
                7. 不要提供id、created_at、updated_at字段，它们会自动生成
                
                其他注意事项：
                1. 如果是模糊查询，使用LIKE操作符
                2. 如果涉及年龄范围，使用BETWEEN或大于小于操作符
                3. 状态字段值必须是ACTIVE、INACTIVE或SUSPENDED之一
                4. 字段名必须与表结构完全匹配
                5. 置信度应该根据问题的明确程度来设定
                """;
    }

    /**
     * 构建用户提示词
     */
    private String buildUserPrompt(String userQuestion) {
        return String.format("请解析以下用户问题的数据库操作意图：\n\n%s", userQuestion);
    }

    /**
     * 从AI响应中解析意图
     */
    private IntentDto.IntentResult parseIntentFromResponse(String response) {
        try {
            // 提取JSON部分（如果AI返回了额外文字）
            String jsonStr = extractJsonFromResponse(response);
            
            IntentDto.IntentResult intent = objectMapper.readValue(jsonStr, IntentDto.IntentResult.class);
            
            // 验证解析结果
            validateIntent(intent);
            
            return intent;
        } catch (Exception e) {
            log.error("解析AI响应失败，响应内容: {}", response, e);
            
            // 返回默认意图
            IntentDto.IntentResult fallbackIntent = new IntentDto.IntentResult();
            fallbackIntent.setOperation(IntentDto.OperationType.UNKNOWN);
            fallbackIntent.setOriginalQuestion(response);
            fallbackIntent.setConfidence(0.0);
            
            return fallbackIntent;
        }
    }

    /**
     * 从响应中提取JSON字符串
     */
    private String extractJsonFromResponse(String response) {
        // 查找JSON开始和结束位置
        int startIndex = response.indexOf("{");
        int endIndex = response.lastIndexOf("}");
        
        if (startIndex >= 0 && endIndex >= 0 && endIndex > startIndex) {
            return response.substring(startIndex, endIndex + 1);
        }
        
        // 如果没有找到完整的JSON，尝试整个响应
        return response.trim();
    }

    /**
     * 验证意图解析结果
     */
    private void validateIntent(IntentDto.IntentResult intent) {
        if (intent.getOperation() == null) {
            intent.setOperation(IntentDto.OperationType.UNKNOWN);
        }
        
        if (intent.getConfidence() == null || intent.getConfidence() < 0 || intent.getConfidence() > 1) {
            intent.setConfidence(0.5);
        }
        
        // 确保表名存在（如果需要的话）
        if (intent.getTableName() == null && 
            intent.getOperation() != IntentDto.OperationType.UNKNOWN) {
            intent.setTableName("users"); // 默认表
        }
    }

    /**
     * 检查意图是否有效
     */
    public boolean isValidIntent(IntentDto.IntentResult intent) {
        return intent != null && 
               intent.getOperation() != IntentDto.OperationType.UNKNOWN &&
               intent.getConfidence() != null &&
               intent.getConfidence() > 0.3;
    }
}